/*
 * ServerSocket.cpp
 *
 * Author: Grupo Nro.
 */

#include "ServerSocket.h"

ServerSocket::ServerSocket(int puerto) {
	this->puerto = puerto;
}

ServerSocket::~ServerSocket() {
}

void ServerSocket::crearSocket(){
	//Creo el socket
	if ((this->sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){
		string mensajeError = "Error al crear socket.";
		throw ComunicacionException(mensajeError, true);
	}
}

void ServerSocket::bindear(){
	struct sockaddr_in serv_addr;
	//Lleno de ceros la estructura
	memset((char*)&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET; //Ordenacion de bytes de la maquina
	serv_addr.sin_port = htons(this->puerto);
	serv_addr.sin_addr.s_addr = INADDR_ANY;
	int habilitar = 1;
		setsockopt(this->sockfd, SOL_SOCKET, SO_REUSEADDR, &habilitar,
				sizeof(int));
	//Enlazo la direccion al socket
	if (bind(this->sockfd, (struct sockaddr *)&serv_addr,
			(socklen_t)sizeof(struct sockaddr_in)) < 0){
		string mensajeError = "Error al bindear.";
		throw ComunicacionException(mensajeError, true);
	}
}

void ServerSocket::escucharConexiones(){
	//Escucho por conexiones
	listen(this->sockfd, CANT_CONEXIONES);
}


int ServerSocket::getSockfd(){
	return this->sockfd;
}

void ServerSocket::conectar(){
	this->crearSocket();
	this->bindear();
	this->escucharConexiones();
}

int ServerSocket::aceptarConexion(){
	int sockfdCliente = 0;
	struct sockaddr_in cli_addr;
	socklen_t socksize = sizeof(struct sockaddr_in);

	//Acepto la conexion entrante y establezco comunicacion
	sockfdCliente = accept(this->sockfd, (struct sockaddr *)&cli_addr, &socksize);
	if (sockfdCliente < 0){
		string mensajeError = "Error aceptando la conexion entrante.";
		throw ComunicacionException(mensajeError, true);
	}

	//Comunicacion establecida
	return sockfdCliente;
}

void ServerSocket::shutdownConexion(int & sockfd){
	if (sockfd > 0){
		shutdown(sockfd, SHUT_RDWR);
	}
}

void ServerSocket::matarConexion(int & sockfd){
	if (sockfd > 0){
		close(sockfd);
		sockfd = -1;
	}
}
